/* =============================== 界面元素 =============================== */
import type {
  ElementCategoriesConfig,
  ProcessedElementConfig,
} from '../../types/constants'
import { createElementConfig, HOSTNAME, SUPPORTED_PLATFORMS } from '../../types/constants'
import {
  BAI_DU_WEB_ELEMENT_CONFIG,
  BIAN_WEB_ELEMENT_CONFIG,
  BILIBILI_VIDEO_WEB_ELEMENT_CONFIG,
  BILIBILI_WEB_ELEMENT_CONFIG,
  CSDN_WEB_ELEMENT_CONFIG,
  FIVE_ONE_CTO_WEB_ELEMENT_CONFIG,
  GREASY_FORK_WEB_ELEMENT_CONFIG,
  ICONFONT_WEB_ELEMENT_CONFIG,
  JIAN_SHU_WEB_ELEMENT_CONFIG,
  JUE_JIN_WEB_ELEMENT_CONFIG,
  ZHI_HU_QUESTION_WEB_ELEMENT_CONFIG,
  ZHI_HU_WEB_ELEMENT_CONFIG,
} from './web_element_config'
import { BING_WEB_ELEMENT_CONFIG } from './web_element_config/bing'
import { GITEE_WEB_ELEMENT_CONFIG } from './web_element_config/gitee'
import { GITHUB_WEB_ELEMENT_CONFIG } from './web_element_config/github'
import { GOOGLE_WEB_ELEMENT_CONFIG } from './web_element_config/google'
import { SO_WEB_ELEMENT_CONFIG } from './web_element_config/so'
import { SO_GOU_WEB_ELEMENT_CONFIG } from './web_element_config/sogou'

export class WebElement {
  static instance: WebElement
  private readonly rules: ElementCategoriesConfig = {
    [SUPPORTED_PLATFORMS.CSDN]: CSDN_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.JUE_JIN]: JUE_JIN_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.ZHI_HU]: ZHI_HU_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.JIAN_SHU]: JIAN_SHU_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.BAI_DU]: BAI_DU_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.GOOGLE]: GOOGLE_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.BING]: BING_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.SO_GOU]: SO_GOU_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.SO]: SO_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.FIVE_ONE_CTO]: FIVE_ONE_CTO_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.ZHI_HU_QUESTION]: ZHI_HU_QUESTION_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.GREASY_FORK]: GREASY_FORK_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.BILIBILI]: BILIBILI_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.BILIBILI_VIDEO]: BILIBILI_VIDEO_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.ICONFONT]: ICONFONT_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.BIAN]: BIAN_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.GITEE]: GITEE_WEB_ELEMENT_CONFIG,
    [SUPPORTED_PLATFORMS.GITHUB]: GITHUB_WEB_ELEMENT_CONFIG,
  }

  static getInstance(): WebElement {
    if (!WebElement.instance)
      WebElement.instance = new WebElement()
    return WebElement.instance
  }

  getConfigs(): ElementCategoriesConfig {
    return this.rules
  }

  getSelectors(options?: { hostname?: string, ignorePlatformCheck?: boolean }): ProcessedElementConfig[] {
    const { hostname = HOSTNAME, ignorePlatformCheck = false } = options || {}

    return Object.entries(this.rules)
      .filter(([platform]) => !ignorePlatformCheck && platform === hostname)
      .reduce((result, [_platform, configData]) => {
        return result.concat(
          Object.entries(configData).map(([identifier, config]) =>
            createElementConfig(identifier, config),
          ),
        )
      }, [] as ProcessedElementConfig[])
  }

  getConfig(name: string, selector: string): ProcessedElementConfig | undefined {
    return Object.values(this.getSelectors()).find(
      config => config.selector === selector && config.nameEn === name,
    )
  }
}
